package com.ysu.zyw.common.util;

import org.springframework.util.Assert;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * FileUtil provide an set of operation to file.
 * <p>
 * Created by ZeRur on 2016/1/17.
 *
 * @author yaowu.zhang
 */
public class FileUtil {

    /**
     * load file's content as a string.
     *
     * @param filepath filepath
     * @return content string
     * @throws IOException
     */
    public static String loadFileAsString(String filepath) throws IOException {
        Assert.hasText(filepath, "empty filepath is not allowed");
        return loadFileAsString(new File(filepath));
    }

    /**
     * load file's content as a string.
     *
     * @param file file
     * @return content string
     * @throws IOException
     */
    public static String loadFileAsString(File file) throws IOException {
        Assert.notNull(file, "null file is not allowed");
        return loadFileAsString(new FileInputStream(file));
    }

    /**
     * load file's content as a string.
     *
     * @param inputStream inputStream
     * @return content string
     * @throws IOException
     */
    public static String loadFileAsString(InputStream inputStream) throws IOException {
        Assert.notNull(inputStream, "null inputStream is not allowed");
        StringBuilder content = new StringBuilder();
        try (BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(inputStream, Charset.defaultCharset()))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                content.append(line).append(System.getProperty("line.separator"));
            }
            return content.toString();
        }
    }

    /**
     * copy file
     *
     * @param srcFilePath  src
     * @param destFilePath dest
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void copyFile(String srcFilePath, String destFilePath) throws IOException {
        Assert.hasText(srcFilePath, "empty src file path is not allowed");
        Assert.hasText(destFilePath, "empty dest file path is not allowed");
        copyFile(new File(srcFilePath), new File(destFilePath));
    }

    /**
     * copy file
     *
     * @param srcFile  src
     * @param destFile dest
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void copyFile(File srcFile, File destFile) throws IOException {
        Assert.notNull(srcFile, "null src file is not allowed");
        Assert.notNull(destFile, "null dest file is not allowed");
        try (FileInputStream fileInputStream = new FileInputStream(srcFile);
             FileOutputStream fileOutputStream = new FileOutputStream(destFile)) {
            FileChannel inFileChannel = fileInputStream.getChannel();
            FileChannel outFileChannel = fileOutputStream.getChannel();
            outFileChannel.transferFrom(inFileChannel, 0, inFileChannel.size());
        }
    }

    /**
     * get content type of a file.
     *
     * @param file file
     * @return content type
     * @throws IOException
     */
    public static String getContentType(File file) throws IOException {
        Assert.notNull(file, "null file is not allowed");
        return getContentType(file.getAbsolutePath());
    }

    /**
     * get content type of a file.
     *
     * @param filepath file
     * @return content type
     * @throws IOException
     */
    public static String getContentType(String filepath) throws IOException {
        Assert.hasText(filepath, "empty filepath is not allowed");
        Path path = Paths.get(filepath);
        return Files.probeContentType(path);
    }

    /**
     * normalize path url, transform all windows splitter '\\' to linux splitter '/'.
     *
     * @param path path url
     * @return normalized path
     */
    public static String normalizePath(String path) {
        Assert.hasText(path, "empty path is not allowed");
        return path.replace("\\", "/");
    }

}